package com.pro01.backend.service;

import com.pro01.backend.constants.LotteryPrize;
import com.pro01.backend.mapper.LotteryLogMapper;
import com.pro01.backend.mapper.UserMapper;
import com.pro01.backend.mapper.UserPointMapper;
import com.pro01.backend.pojo.LotteryLog;
import com.pro01.backend.pojo.PageResult;
import com.pro01.backend.pojo.PointLog;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Random;

@Service
public class LotteryService {

    private static final int LOTTERY_COST = 50; // 每次抽奖消耗积分

    @Autowired
    private UserPointMapper userPointMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LotteryLogMapper lotteryLogMapper;

    @Autowired
    private PointLogService pointLogService;  // 负责积分日志（如果有）

    // ✅ 重新定义带权重奖池
    private static final List<PrizeWeight> PRIZE_POOL = List.of(
            new PrizeWeight(LotteryPrize.TITLE_LUCKY, 10),     // 称号
            new PrizeWeight(LotteryPrize.FRAME_LUCKY, 10),     // 头像框
            new PrizeWeight(LotteryPrize.POINTS_200, 10),      // 积分200
            new PrizeWeight(LotteryPrize.POINTS_100, 20),      // 积分100
            new PrizeWeight(LotteryPrize.POINTS_20, 20),       // 积分20
            new PrizeWeight(LotteryPrize.NONE, 30)             // 谢谢参与
    );

    // ✅ 内部静态类 PrizeWeight
    @Getter
    @AllArgsConstructor
    public static class PrizeWeight {
        private LotteryPrize prize;
        private int weight;
    }

    private final Random random = new Random();

    public LotteryPrize doLottery(Long userId) {
        // 1. 检查用户积分是否足够
        Integer points = userPointMapper.getUserPoints(userId);
        if (points == null || points < LOTTERY_COST) {
            throw new RuntimeException("积分不足，无法抽奖！");
        }

        // 2. 扣除积分
        userPointMapper.subtractPoints(userId, LOTTERY_COST);

        // ✅ 补充：写积分扣除日志
        pointLogService.logExpense(userId, LOTTERY_COST, "抽奖消耗积分");

        // 3. 抽取奖品
        LotteryPrize prize = randomDraw();

        // 4. 发放奖品
        switch (prize.getType()) {
            case "POINTS":
                int pointsAwarded = Integer.parseInt(prize.getValue());
                userPointMapper.addPoints(userId, pointsAwarded);

                // 写积分日志（加分）
                pointLogService.logIncome(userId, pointsAwarded, "抽奖获得积分奖励");
                break;

            case "USER_TITLE":
                userMapper.updateUserTitle(userId, prize.getValue());
                break;

            case "AVATAR_FRAME":
                userMapper.updateAvatarFrame(userId, prize.getValue());
                break;

            case "NONE":
                // 谢谢参与，无需处理
                break;
        }

        // 5. 写入抽奖记录
        LotteryLog log = new LotteryLog();
        log.setUserId(userId);
        log.setPrizeName(prize.getName());
        log.setPrizeType(prize.getType());
        log.setPrizeValue(prize.getValue());
        lotteryLogMapper.insertLotteryLog(log);

        return prize;
    }

//    private LotteryPrize randomDraw() {
//        // 简单均匀随机，后期可以改成加权随机
//        int index = random.nextInt(PRIZE_POOL.size());
//        return PRIZE_POOL.get(index);
//    }

    // ✅ 加权随机方法
    private LotteryPrize randomDraw() {
        int rand = random.nextInt(100); // [0, 99]
        int cumulative = 0;

        for (PrizeWeight pw : PRIZE_POOL) {
            cumulative += pw.getWeight();
            if (rand < cumulative) {
                return pw.getPrize();
            }
        }
        return LotteryPrize.NONE; // 保险兜底
    }

    // 用户查看自己的抽奖记录
    public PageResult<LotteryLog> getUserLotteryLogs(Long userId, int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        List<LotteryLog> records = lotteryLogMapper.getLogsByUser(userId, offset, pageSize);
        int total = lotteryLogMapper.countLogsByUser(userId);
        return new PageResult<>(total, records);
    }

    // 用户查看当前剩余积分
    public int getCurrentUserPoints(Long userId) {
        Integer points = userPointMapper.getUserPoints(userId);
        return points != null ? points : 0;
    }

    /**
     * 下面是管理员接口
     */

    // 管理员查看抽奖记录
    public PageResult<Map<String, Object>> getAllLotteryLogs(int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        List<Map<String, Object>> records = lotteryLogMapper.getAllLogsPaged(offset, pageSize);
        int total = lotteryLogMapper.countAllLogs();
        return new PageResult<>(total, records);
    }

    // 管理员查看抽奖记录统计
    public List<Map<String, Object>> getLotteryStats() {
        List<Map<String, Object>> stats = lotteryLogMapper.getPrizeStats();
        int total = lotteryLogMapper.countTotalDraws();

        for (Map<String, Object> stat : stats) {
            long count = (long) stat.get("count");
            double ratio = total == 0 ? 0 : (count * 100.0 / total);
            stat.put("ratio", String.format("%.2f%%", ratio));
        }

        return stats;
    }

}
